namespace Microsoft.ServiceModel.Samples.Discovery
{
    using System;
    using System.Xml;
    using System.Xml.Serialization;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using Microsoft.ServiceModel.Samples.Discovery.Protocol;
    
    [XmlRoot(ElementName = ProtocolStrings.ScopesElement,
        Namespace = ProtocolStrings.Namespace)]
    public class ScopeCollection : Collection<Uri>, IXmlSerializable
    {
        Uri matchBy;
        Collection<XmlAttribute> anyAttributes;

        public ScopeCollection(): base()
        {
            Initialize();
        }

        void Initialize()
        {
            this.matchBy = null;
            this.anyAttributes = new Collection<XmlAttribute>();
        }

        internal Uri MatchBy
        {
            get
            {
                return this.matchBy;
            }

            set
            {
                this.matchBy = value;
            }
        }

        public Collection<XmlAttribute> AnyAttributes
        {
            get
            {
                return this.anyAttributes;
            }
        }

        #region IXmlSerializable Members

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            List<Uri> _uris = null;
            Collection<XmlAttribute> _anyAttributes = new Collection<XmlAttribute>();
            Uri _matchBy = null;

            // read all atrributes including matchby
            if (reader.HasAttributes) 
            {
                XmlDocument doc = new XmlDocument();
                
                while (reader.MoveToNextAttribute()) 
                {
                    if ((reader.NamespaceURI.Length == 0) &&
                        (reader.Name.Equals(ProtocolStrings.MatchByAttribute)))
                    {
                        _matchBy = new Uri(reader.Value);
                    }
                    else
                    {
                        XmlAttribute attr = doc.CreateAttribute(reader.Name, 
                            reader.NamespaceURI);

                        attr.Value = reader.Value;
                        _anyAttributes.Add(attr);
                    }
                }

                reader.MoveToElement();
            }
                
            // read the Uri list.
            _uris = SerializationUtility.ReadContentAsListOfUris(reader);

            // read end element Scopes.
            reader.ReadEndElement();

            // the read was success, update the current values.
            this.Clear();
            foreach (Uri uri in _uris)
                this.Add(uri);

            this.anyAttributes = _anyAttributes;
            this.matchBy = _matchBy;
        }

        public void WriteXml(XmlWriter writer)
        {
            if (this.matchBy != null)
            {
                // 1. write MatchBy attribue.
                writer.WriteAttributeString(ProtocolStrings.MatchByAttribute,
                    string.Empty,
                    MatchBy.GetComponents(UriComponents.SerializationInfoString,
                        UriFormat.UriEscaped));
            }

            // 2. write other extensibility attributes.
            if ((anyAttributes != null) && (anyAttributes.Count > 0))
            {
                foreach (XmlAttribute anyAttr in anyAttributes)
                    anyAttr.WriteTo(writer);
            }

            // 3. Write the content as string of Uris
            SerializationUtility.WriteListOfUris(writer, this);
        }

        #endregion
    }
}
